import {Point} from '../../type';
import {PlotTypes} from '../../enum/PlotTypes';
import * as PlotUtils from '../../utils';
import * as Constants from '../../constants';
import {
    calculateNewCoordinateOfRotate,
    calculateNewCoordinateOfScale,
    calculateNewCoordinateOfTranslate
} from '../../utils';

// @ts-ignore
export default class FineArrow extends ol.geom.Polygon {
    public params: any;
    public isPlot: boolean = true;
    public fixPointCount: number = 2;
    public tailWidthFactor: number = 0.1;
    public neckWidthFactor: number = 0.2;
    public headWidthFactor: number = 0.25;
    public headAngle: number = Math.PI / 8.5;
    public neckAngle: number = Math.PI / 13;

    private readonly _type: PlotTypes;
    private points: Array<Point>;

    constructor(coordinates: any, points: Array<Point>, params: any) {
        super([]);
        this._type = PlotTypes.FINE_ARROW;
        this.points = [];
        this.params = params;
        if (points && points.length > 0) {
            this.setPoints(points);
        } else if (coordinates && coordinates.length > 0) {
            // @ts-ignore
            this.setCoordinates(coordinates);
        }
    }

    public transform(type: string, params: any): any {
        if (type === 'scale') {
            const {scaleX, scaleY, centerX, centerY, paths} = params;
            const newPoints = calculateNewCoordinateOfScale([scaleX, scaleY], [centerX, centerY], paths);
            this.setPoints(newPoints);
        } else if (type === 'rotate') {
            const {angle, centerX, centerY, paths} = params;
            const newPaths = calculateNewCoordinateOfRotate(paths, [centerX, centerY], angle);
            this.setPoints(newPaths);
        } else if (type === 'translate') {
            const {deltaX, deltaY, centerX, centerY, paths} = params;
            const newPoints = calculateNewCoordinateOfTranslate(paths, [deltaX, deltaY]);
            this.setPoints(newPoints);
        }
    }

    /**
     * 获取标绘类型
     * @return {PlotTypes}
     */
    public getPlotType(): PlotTypes {
        return this._type;
    }

    /**
     * 获取坐标点
     * @return {Array<Point>}
     */
    public getPoints(): Array<Point> {
        return this.points.slice(0);
    }

    /**
     * 获取点数理
     * @return {number}
     */
    public getPointCount(): number {
        return this.points.length;
    }

    /**
     * 更新当前坐标
     * @param point
     * @param index
     */
    public updatePoint(point: Point, index: number): void {
        if (index >= 0 && index < this.points.length) {
            this.points[index] = point;
            this.generate();
        }
    }

    private updateLastPoint(point: Point): void {
        this.updatePoint(point, this.points.length - 1);
    }

    /**
     * 完成绘制
     */
    public finishDrawing(): void {
    }

    private setPoints(value: Array<Point>): void {
        this.points = !value ? [] : value;
        if (this.points.length >= 1) {
            this.generate();
        }
    }

    private generate(): void {
        try {
            let count: number = this.getPointCount();
            if (count < 2) {
                return;
            } else {
                let points: Array<Point> = this.getPoints();
                let [pnt1, pnt2]: [pnt1: Point, pnt2: Point] = [points[0], points[1]];
                let len: number = PlotUtils.getBaseLength(points);
                let tailWidth: number = len * this.tailWidthFactor;
                let neckWidth: number = len * this.neckWidthFactor;
                let headWidth: number = len * this.headWidthFactor;
                let tailLeft: Point = PlotUtils.getThirdPoint(pnt2, pnt1, Constants.HALF_PI, tailWidth, true);
                let tailRight: Point = PlotUtils.getThirdPoint(pnt2, pnt1, Constants.HALF_PI, tailWidth, false);
                let headLeft: Point = PlotUtils.getThirdPoint(pnt1, pnt2, this.headAngle, headWidth, false);
                let headRight: Point = PlotUtils.getThirdPoint(pnt1, pnt2, this.headAngle, headWidth, true);
                let neckLeft: Point = PlotUtils.getThirdPoint(pnt1, pnt2, this.neckAngle, neckWidth, false);
                let neckRight: Point = PlotUtils.getThirdPoint(pnt1, pnt2, this.neckAngle, neckWidth, true);
                let pList = [tailLeft, neckLeft, headLeft, pnt2, headRight, neckRight, tailRight];
                // @ts-ignore
                this.setCoordinates([pList]);
            }
        } catch (e) {
            console.log(e);
        }
    }
}
